PHP Conference Japan 2024

NumberFormatter 類別

(PHP 5 >= 5.3.0,PHP 7,PHP 8,PECL intl >= 1.0.0)

簡介

程式使用與操作數字時,會採用與地區設定無關的二進位表示法。當顯示或列印數字時,會將其轉換為符合地區設定的字串。例如,數字 12345.67 在美國是 "12,345.67",在法國是 "12 345,67",而在德國是 "12.345,67"。

透過調用 NumberFormatter 類別提供的方法,您可以根據指定的或預設的地區設定格式化數字、貨幣和百分比。NumberFormatter 對地區設定敏感,因此您需要為每個地區設定建立新的 NumberFormatter。NumberFormatter 方法格式化基本型別數字,例如 double,並將數字輸出為符合地區設定的字串。

對於貨幣,您可以使用貨幣格式型別來建立格式器,該格式器會傳回包含格式化數字和適當貨幣符號的字串。當然,NumberFormatter 類別不知道匯率,因此,無論指定的貨幣為何,數字輸出都相同。這表示相同的數字,會因貨幣地區設定而有不同的貨幣價值。如果數字是 9988776.65,結果將會是

  • 在法國是 9 988 776,65 €
  • 在德國是 9.988.776,65 €
  • 在美國是 $9,988,776.65

為了格式化百分比,請使用百分比格式型別建立符合地區設定的格式器。使用此格式器,小數(例如 0.75)會顯示為 75%。

對於更複雜的格式化,例如拼寫出的數字,會使用基於規則的數字格式器。

類別綱要

class NumberFormatter {
/* 常數 */
public const int PATTERN_DECIMAL;
public const int DECIMAL;
public const int CURRENCY;
public const int PERCENT;
public const int SCIENTIFIC;
public const int SPELLOUT;
public const int ORDINAL;
public const int DURATION;
public const int PATTERN_RULEBASED;
public const int IGNORE;
public const int CURRENCY_ACCOUNTING;
public const int DEFAULT_STYLE;
public const int ROUND_CEILING;
public const int ROUND_FLOOR;
public const int ROUND_DOWN;
public const int ROUND_UP;
public const int ROUND_TOWARD_ZERO;
public const int ROUND_HALFEVEN;
public const int ROUND_HALFODD;
public const int ROUND_HALFDOWN;
public const int ROUND_HALFUP;
public const int PAD_BEFORE_PREFIX;
public const int PAD_AFTER_PREFIX;
public const int PAD_BEFORE_SUFFIX;
public const int PAD_AFTER_SUFFIX;
public const int PARSE_INT_ONLY;
public const int GROUPING_USED;
public const int MAX_INTEGER_DIGITS;
public const int MIN_INTEGER_DIGITS;
public const int INTEGER_DIGITS;
public const int MAX_FRACTION_DIGITS;
public const int MIN_FRACTION_DIGITS;
public const int FRACTION_DIGITS;
public const int MULTIPLIER;
public const int GROUPING_SIZE;
public const int ROUNDING_MODE;
public const int ROUNDING_INCREMENT;
public const int FORMAT_WIDTH;
public const int PADDING_POSITION;
public const int LENIENT_PARSE;
public const int POSITIVE_PREFIX;
public const int POSITIVE_SUFFIX;
public const int NEGATIVE_PREFIX;
public const int NEGATIVE_SUFFIX;
public const int PADDING_CHARACTER;
public const int CURRENCY_CODE;
public const int DEFAULT_RULESET;
public const int PUBLIC_RULESETS;
public const int PERCENT_SYMBOL;
public const int ZERO_DIGIT_SYMBOL;
public const int DIGIT_SYMBOL;
public const int MINUS_SIGN_SYMBOL;
public const int PLUS_SIGN_SYMBOL;
public const int CURRENCY_SYMBOL;
public const int EXPONENTIAL_SYMBOL;
public const int PERMILL_SYMBOL;
public const int PAD_ESCAPE_SYMBOL;
public const int INFINITY_SYMBOL;
public const int NAN_SYMBOL;
public const int TYPE_DEFAULT;
public const int TYPE_INT32;
public const int TYPE_INT64;
public const int TYPE_DOUBLE;
public const int TYPE_CURRENCY;
/* 方法 */
public __construct(string $locale, int $style, ?string $pattern = null)
public static create(string $locale, int $style, ?string $pattern = null): ?NumberFormatter
public format(int|float $num, int $type = NumberFormatter::TYPE_DEFAULT): string|false
public formatCurrency(float $amount, string $currency): string|false
public getAttribute(int $attribute): int|float|false
public getErrorCode(): int
public getSymbol(int $symbol): string|false
public getTextAttribute(int $attribute): string|false
public parse(string $string, int $type = NumberFormatter::TYPE_DOUBLE, int &$offset = null): int|float|false
public parseCurrency(string $string, string &$currency, int &$offset = null): float|false
public setAttribute(int $attribute, int|float $value): bool
public setPattern(string $pattern): bool
public setSymbol(int $symbol, string $value): bool
public setTextAttribute(int $attribute, string $value): bool
}

預定義常數

格式類型

這些樣式被 numfmt_create() 用來定義格式化器的類型。

NumberFormatter::PATTERN_DECIMAL int
由樣式定義的十進制格式
NumberFormatter::DECIMAL int
十進制格式
NumberFormatter::CURRENCY int
貨幣格式
NumberFormatter::PERCENT int
百分比格式
NumberFormatter::SCIENTIFIC int
科學記號格式
NumberFormatter::SPELLOUT int
基於規則的拼寫格式
NumberFormatter::ORDINAL int
基於規則的序數格式
NumberFormatter::DURATION int
基於規則的持續時間格式
NumberFormatter::PATTERN_RULEBASED int
由樣式定義的基於規則的格式
NumberFormatter::CURRENCY_ACCOUNTING int
用於會計的貨幣格式,例如負數金額使用 ($3.00) 而不是 -$3.00。自 PHP 7.4.1 和 ICU 53 起可用。
NumberFormatter::DEFAULT_STYLE int
該地區的預設格式
NumberFormatter::IGNORE int
PATTERN_DECIMAL 的別名

數字格式指定符

這些常數定義數字如何被解析或格式化。它們應該作為 numfmt_format()numfmt_parse() 的引數使用。

NumberFormatter::TYPE_DEFAULT int
從變數類型推斷類型
NumberFormatter::TYPE_INT32 int
格式化/解析為 32 位元整數
NumberFormatter::TYPE_INT64 int
格式化/解析為 64 位元整數
NumberFormatter::TYPE_DOUBLE int
格式化/解析為浮點數值
NumberFormatter::TYPE_CURRENCY int
格式化/解析為貨幣值。自 PHP 8.3.0 起已棄用

數字格式屬性

numfmt_get_attribute()numfmt_set_attribute() 使用的數字格式屬性。

NumberFormatter::PARSE_INT_ONLY int
僅解析整數。
NumberFormatter::GROUPING_USED int
使用分組分隔符。
NumberFormatter::DECIMAL_ALWAYS_SHOWN int
總是顯示小數點。
NumberFormatter::MAX_INTEGER_DIGITS int
最大整數位數。
NumberFormatter::MIN_INTEGER_DIGITS int
最小整數位數。
NumberFormatter::INTEGER_DIGITS int
整數位數。
NumberFormatter::MAX_FRACTION_DIGITS int
最大小數位數。
NumberFormatter::MIN_FRACTION_DIGITS int
最小小數位數。
NumberFormatter::FRACTION_DIGITS int
小數位數。
NumberFormatter::MULTIPLIER int
乘數。
NumberFormatter::GROUPING_SIZE int
分組大小。
NumberFormatter::ROUNDING_MODE int
捨入模式。
NumberFormatter::ROUNDING_INCREMENT int
捨入增量。
NumberFormatter::FORMAT_WIDTH int
格式化輸出時要填補的寬度。
NumberFormatter::PADDING_POSITION int
填補將發生在哪個位置。請參閱可能的參數值的填補位置常數。
NumberFormatter::SECONDARY_GROUPING_SIZE int
次要分組大小。
NumberFormatter::SIGNIFICANT_DIGITS_USED int
使用有效位數。
NumberFormatter::MIN_SIGNIFICANT_DIGITS int
最小有效位數。
NumberFormatter::MAX_SIGNIFICANT_DIGITS int
最大有效位數。
NumberFormatter::LENIENT_PARSE int
規則式格式所使用的寬鬆解析模式。

數字格式文字屬性

numfmt_get_text_attribute()numfmt_set_text_attribute() 使用的數字格式文字屬性。

NumberFormatter::POSITIVE_PREFIX int
正數前綴。
NumberFormatter::POSITIVE_SUFFIX int
正數後綴。
NumberFormatter::NEGATIVE_PREFIX int
負數前綴。
NumberFormatter::NEGATIVE_SUFFIX int
負數後綴。
NumberFormatter::PADDING_CHARACTER int
用於填補格式寬度的字元。
NumberFormatter::CURRENCY_CODE int
ISO 貨幣代碼。
NumberFormatter::DEFAULT_RULESET int
預設規則集。這僅適用於規則式格式化器。
NumberFormatter::PUBLIC_RULESETS int
公開規則集。這僅適用於規則式格式化器。這是一個唯讀屬性。公開規則集會以單一字串傳回,每個規則集名稱以 ';' (分號) 分隔。

捨入模式

numfmt_get_attribute()numfmt_set_attribute() 搭配 NumberFormatter::ROUNDING_MODE 屬性使用的捨入模式值。

NumberFormatter::ROUND_AWAY_FROM_ZERO
NumberFormatter::ROUND_UP 的別名。
NumberFormatter::ROUND_CEILING int
捨入模式,將數值朝正無限大方向捨入。
NumberFormatter::ROUND_DOWN int
捨入模式,將數值朝零方向捨入。
NumberFormatter::ROUND_FLOOR int
捨入模式,將數值朝負無限大方向捨入。
NumberFormatter::ROUND_HALFDOWN int
捨入模式,將數值朝「最接近的鄰近數」捨入,除非兩個鄰近數的距離相等,在這種情況下會捨去。
NumberFormatter::ROUND_HALFEVEN int
捨入模式,將數值朝「最接近的鄰近數」捨入,除非兩個鄰近數的距離相等,在這種情況下,會朝偶數鄰近數捨入。
NumberFormatter::ROUND_HALFODD
捨入模式,將數值朝「奇數鄰近數」捨入。
NumberFormatter::ROUND_HALFUP int
捨入模式,將數值朝「最接近的鄰近數」捨入,除非兩個鄰近數的距離相等,在這種情況下會進位。
NumberFormatter::ROUND_TOWARD_ZERO
NumberFormatter::ROUND_DOWN 的別名。
NumberFormatter::ROUND_UP int
捨入模式,將數值捨離零。

填補指定符

numfmt_get_attribute()numfmt_set_attribute() 搭配 NumberFormatter::PADDING_POSITION 屬性使用的填補位置值。

NumberFormatter::PAD_AFTER_PREFIX int
在字首後插入填補字元。
NumberFormatter::PAD_AFTER_SUFFIX int
在字尾後插入填補字元。
NumberFormatter::PAD_BEFORE_PREFIX int
在字首前插入填補字元。
NumberFormatter::PAD_BEFORE_SUFFIX int
在後綴之前插入填充字元。

更新日誌

版本 描述
8.4.0 類別常數現在具有型別。

目錄

新增筆記

使用者貢獻的筆記 8 筆記

49
giorgio dot liscio at email dot it
13 年前
這個類別似乎很麻煩:事實並非如此,格式化和解析具有高度的客製化能力,但您可能真正需要的是非常簡單的東西

如果您想要本地化數字,請使用

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::DECIMAL);
echo
$a->format(12345.12345) . "<br>"; // 輸出 12.345,12
$a->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 0);
$a->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 100); // 預設情況下,某些地區設定的最大小數位數為 2,這可能不是您想要的
echo $a->format(12345.12345) . "<br>"; // 輸出 12.345,12345
?>

如果您想要列印貨幣,請使用

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
echo
$a->format(12345.12345) . "<br>"; // 輸出 €12.345,12
?>

如果您有以(例如)美元儲存的貨幣資料,並且您想要使用 it-IT 表示法列印它們,您需要使用

<?php
$a
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
echo
$a->formatCurrency(12345, "USD") . "<br>"; // 輸出 $ 12.345,00,並使用義大利表示法(逗號作為小數分隔符)格式化
?>

另一個關於貨幣的實用範例(如何透過地區設定字串取得貨幣名稱)

<?php
$frontEndFormatter
= new \NumberFormatter("it-IT", \NumberFormatter::CURRENCY);
$adminFormatter = new \NumberFormatter("en-US", \NumberFormatter::CURRENCY);
$symbol = $adminFormatter->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL); // 取得 USD
echo $frontEndFormatter->formatCurrency(12345.12345, $symbol) . "<br>";
?>
3
jimbo2150 at gmail dot com
1 年前
NumberFormatter 類別可以用來將整數數字轉換為羅馬數字,而無需使用符號和關聯值的陣列自訂函數

<?php

function intToRomanNumeral(int $num) {
static
$nf = new NumberFormatter('@numbers=roman', NumberFormatter::DECIMAL);
return
$nf->format($num);
}

echo
intToRomanNumeral(2); // II

echo intToRomanNumeral(5); // V

echo intToRomanNumeral(10); // X

echo intToRomanNumeral(50); // L

echo intToRomanNumeral(57); // LVII
echo intToRomanNumeral(58); // LVIII

echo intToRomanNumeral(100); // C

echo intToRomanNumeral(150); // CL

echo intToRomanNumeral(1000); // M

echo intToRomanNumeral(10000); // ↂ

?>
2
stan at dragnev dot ca
4 年前
這裡有一個如何使用 PATTERN_DECIMAL 列印具有兩個小數位數的數字,使用 () 表示負數,並使用空格作為填充字元,在小數點左側填充到五個字元的範例

<?php

$fmt
= new NumberFormatter("en-CA", NumberFormatter::PATTERN_DECIMAL, "* #####.00 ;(* #####.00)");
echo
$fmt->format(-45.1);

// 輸出: " (45.10)"

?>

請注意,樣式中的 ; 表示子樣式的開始,該子樣式用於負數。因此,分號後面的樣式周圍有括號。
0
Einenlum
10 個月前
請注意(至少對於 'fr-FR' 地區設定),NumberFormatter 不使用空格。它甚至不使用不斷行空格 (NBSP)。它使用窄不斷行空格 (NNBSP)。這破壞了我的測試。

<?php

$formatter
= new NumberFormatter(
'fr-FR',
NumberFormatter::DEFAULT_STYLE
);

$value = $formatter->format(100_000); // '100 000'

// 如果您想將窄不間斷空白字元替換為不間斷空白字元:

str_replace("\u{202F}", "\u{00A0}", $value);

// 如果您想將其替換為一般空白字元

str_replace("\u{202F}", " ", $value);
2
sudheer at binaryvibes dot co dot in
13 年前
用於以英文印出數字的範例腳本。

<?php
$f
= new NumberFormatter("en", NumberFormatter::SPELLOUT);
echo
$f->format(123456);

?>

產生以下結果
one hundred twenty-three thousand four hundred fifty-six
0
gwyneth dot llewelyn at gwynethllewelyn dot net
2 年前
當在 PHP 7.3 和 8+ 中使用 `NumberFormatter` 類別來美化列印貨幣時,文件中並未清楚說明您可以使用空字串 "" 作為建構函式的地區設定,而這將會檢索預設的地區設定(無論您的環境中設定為何)。

相對地,`formatCurrency()` 不接受空字串作為預設貨幣符號;它會改為顯示「通用」貨幣符號 (¤)。

已在 Ubuntu Linux 底下的 PHP 7.4.30、8.0.21、8.1.8 和 macOS Big Sur (11.6.8) 底下的 8.1.8 進行測試。我嘗試過其他替代方案(例如在 ARM 晶片上執行的 Linux、PHP 7.3.3),但遺憾的是 `NumberFormatter` 函式庫似乎不存在(或無法找到)在這些系統上...
-2
AF
3 年前
請注意阿拉伯文的小數點分隔符號(https://en.wikipedia.org/wiki/Decimal_separator#Other_numeral_systems)。

以下所有條件皆為真
<?php
(new \NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) === '٫';
(new
\NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) == '٫';

(new
\NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) !== ',';
(new
\NumberFormatter("ar_AE", \NumberFormatter::DEFAULT_STYLE))->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) != ',';
?>
-3
Joey
7 年前
請注意這個類別有時會缺乏足夠的錯誤輸出。我最近在建構函式中傳遞了無效的模式來實例化它。

php -r '$nf = new \NumberFormatter("tlh-KX.UTF8", \NumberFormatter::IGNORE, "{,,#;#}");var_dump($nf->format(5));'

Fatal error: Call to a member function format() on null in Command line code on line 1

而不是發出錯誤訊息或拋出例外,在呼叫 new 之後會傳回 null。

我不確定在 PHP 7 中是否已修正,但這是需要注意的事情。請務必仔細檢查您的參數。
To Top